<!DOCTYPE html>
<html>
<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="utf-8">
  
  <title>scons自动构建工具 | 小魏的博客</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
    <meta name="keywords" content="Vker,Vker's Blog">
  
  <meta name="description" content="这篇文章可能有点长,如果你想要学到一些知识,而不是简单入门,你要有耐心的看下去,当然在看的时候,也要自己思考,也许我写的有问题,这个时候你可以再去看看,官方文档.这个教程由于内容太多,有些还没来得及写.一般我这里不会太多的去,介绍它的历史,和它是干啥的,你可以自己去找度娘去了解.我这里只有逻辑和事例代码. 工具版本: 3.0.1scons user guide scons user guide s">
<meta name="keywords" content="python,c++,scons">
<meta property="og:type" content="article">
<meta property="og:title" content="scons自动构建工具">
<meta property="og:url" content="https://leng521.top/posts/79065537/index.html">
<meta property="og:site_name" content="小魏的博客">
<meta property="og:description" content="这篇文章可能有点长,如果你想要学到一些知识,而不是简单入门,你要有耐心的看下去,当然在看的时候,也要自己思考,也许我写的有问题,这个时候你可以再去看看,官方文档.这个教程由于内容太多,有些还没来得及写.一般我这里不会太多的去,介绍它的历史,和它是干啥的,你可以自己去找度娘去了解.我这里只有逻辑和事例代码. 工具版本: 3.0.1scons user guide scons user guide s">
<meta property="og:locale" content="default">
<meta property="og:updated_time" content="2019-08-14T03:22:53.956Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="scons自动构建工具">
<meta name="twitter:description" content="这篇文章可能有点长,如果你想要学到一些知识,而不是简单入门,你要有耐心的看下去,当然在看的时候,也要自己思考,也许我写的有问题,这个时候你可以再去看看,官方文档.这个教程由于内容太多,有些还没来得及写.一般我这里不会太多的去,介绍它的历史,和它是干啥的,你可以自己去找度娘去了解.我这里只有逻辑和事例代码. 工具版本: 3.0.1scons user guide scons user guide s">
  
  
    <link rel="icon" href="/head.jpg">
  
  <link href="//cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
  <link rel="stylesheet" href="/css/style.css">
  <script src="/js/pace.min.js"></script>
  

  
	<script>
	var _hmt = _hmt || [];
	(function() {
	  var hm = document.createElement("script");
	  hm.src = "//hm.baidu.com/hm.js?2eaff0c5326867354b0d3469d507d209";
	  var s = document.getElementsByTagName("script")[0]; 
	  s.parentNode.insertBefore(hm, s);
	})();
	</script>

  

</head>
</html>
<body>
  <div id="container">
      <header id="header">
    <div id="banner"></div>
    <div id="header-outer">
        <div id="header-menu" class="header-menu-pos animated">
            <div class="header-menu-container">
                <a href="/" class="left">
                    <span class="site-title">Vker&#39;s Blog</span>
                </a>
                <nav id="header-menu-nav" class="right">
                    
                    <a  href="/">
                        <i class="fa fa-home"></i>
                        <span>Home</span>
                    </a>
                    
                    <a  href="/archives">
                        <i class="fa fa-archive"></i>
                        <span>Archives</span>
                    </a>
                    
                    <a  href="/about">
                        <i class="fa fa-user"></i>
                        <span>About</span>
                    </a>
                    
                </nav>
                <a class="mobile-header-menu-button">
                    <i class="fa fa-bars"></i>
                </a>
            </div>
        </div>
        <div id="header-row">
            <div id="logo">
                <a href="/">
                    <img src="/head.jpg" alt="logo">
                </a>
            </div>
            <div class="header-info">
                <div id="header-title">
                    
                    <h2>
                        Vker&#39;s Blog
                    </h2>
                    
                </div>
                <div id="header-description">
                    
                    <h3>
                        一个专注 游戏研发 的技术博客
                    </h3>
                    
                </div>
            </div>
            <nav class="header-nav">
                <div class="social">
                    
                        <a title="Vker" target="_blank" href="//leng521.top">
                            <i class="fa fa-home fa-2x"></i></a>
                    
                        <a title="Github" target="_blank" href="//github.com">
                            <i class="fa fa-github fa-2x"></i></a>
                    
                        <a title="Weibo" target="_blank" href="//weibo.com">
                            <i class="fa fa-weibo fa-2x"></i></a>
                    
                        <a title="Twitter" target="_blank" href="//twitter.com">
                            <i class="fa fa-twitter fa-2x"></i></a>
                    
                </div>
            </nav>
        </div>
    </div>
</header>
      <div class="outer">
        <section id="main" class="body-wrap"><article id="post-scons自动构建工具" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h1 class="post-title" itemprop="name">
      scons自动构建工具
    </h1>
    <div class="post-title-bar">
      <ul>
          
              <li>
                  <i class="fa fa-book"></i>
                  
                      <a href="/categories/自动构建工具/">自动构建工具</a>
                  
              </li>
          
        <li>
          <i class="fa fa-calendar"></i>  2018-12-23
        </li>
        <li>
          <i class="fa fa-eye"></i>
          <span id="busuanzi_value_page_pv"></span>
        </li>
      </ul>
    </div>
  

          
      </header>
    
    <div class="article-entry post-content" itemprop="articleBody">
      
            
            <p>这篇文章可能有点长,如果你想要学到一些知识,而不是简单入门,你要有耐心的看下去,当然在看的时候,也要自己思考,也许我写的有问题,这个时候你可以再去看看,官方文档.<br>这个教程由于内容太多,有些还没来得及写.<br>一般我这里不会太多的去,介绍它的历史,和它是干啥的,你可以自己去找度娘去了解.我这里只有逻辑和事例代码.</p>
<p>工具版本: 3.0.1<br><a href="https://scons.org/doc/production/HTML/scons-user/">scons user guide</a></p>
<p><a href="https://scons.org/doc/production/HTML/scons-user/">scons user guide</a></p>
<h3 id="scons-普通简单的构建"><a href="#scons-普通简单的构建" class="headerlink" title="scons 普通简单的构建"></a>scons 普通简单的构建</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// file name main.cpp</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> <span class="keyword">const</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">using</span> <span class="keyword">namespace</span>  <span class="built_in">std</span>;</span><br><span class="line">    <span class="built_in">cout</span>&lt;&lt; <span class="string">"helloworld"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<a id="more"></a>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env python</span></span><br><span class="line">Program(<span class="string">'main.cpp'</span>)</span><br></pre></td></tr></table></figure>
<h3 id="多个文件构建"><a href="#多个文件构建" class="headerlink" title="多个文件构建"></a>多个文件构建</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env python</span></span><br><span class="line"><span class="comment"># 构建多个文件</span></span><br><span class="line">Program([<span class="string">'main.cpp'</span>,<span class="string">'other.cpp'</span>])</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用 匹配 的方式选择构建的的文件</span></span><br><span class="line"><span class="comment"># 可以使用 Glob()</span></span><br><span class="line"></span><br><span class="line">Program(Glob(<span class="string">'*.cpp'</span>))</span><br><span class="line"></span><br><span class="line">Glob() =&gt; 匹配的方式有个</span><br><span class="line">- * 通配符</span><br><span class="line">- ? 匹配任意一个字符</span><br><span class="line">- [abc] 匹配任意一个符</span><br><span class="line">- [!abc] 输了abc 之外的字符</span><br><span class="line"></span><br><span class="line">Split函数 scons为了方便可以使用 分割函数一空格分割同样做到 多文件编译</span><br><span class="line"></span><br><span class="line">Program(<span class="string">"HelloWorld"</span>,Split(<span class="string">"main.c other.c"</span>))</span><br><span class="line">Program(<span class="string">"HelloWorld"</span>,Split(<span class="string">"""</span></span><br><span class="line"><span class="string">    main.c</span></span><br><span class="line"><span class="string">    other.c"""</span>))</span><br><span class="line">允许使用 多行字符串</span><br><span class="line"></span><br><span class="line">scons 也可以使用指定参数的形式调用</span><br><span class="line"></span><br><span class="line">src_files = Split(<span class="string">'main.c file1.c file2.c'</span>)</span><br><span class="line">Program(target = <span class="string">'program'</span>, source = src_files)</span><br><span class="line"></span><br><span class="line">当然也可以反转参数</span><br><span class="line">src_files = Split(<span class="string">'main.c file1.c file2.c'</span>)</span><br><span class="line">Program(source = src_files, target = <span class="string">'program'</span>)</span><br></pre></td></tr></table></figure>
<h3 id="Object-构建方法"><a href="#Object-构建方法" class="headerlink" title="Object 构建方法"></a>Object 构建方法</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Object(<span class="string">'main.c'</span>)</span><br><span class="line"></span><br><span class="line">在 POSIX 系统上产生 *.o 文件</span><br><span class="line">在 windows 系统上产生 *.obj 文件</span><br></pre></td></tr></table></figure>
<h3 id="清楚构建对中产生的对象"><a href="#清楚构建对中产生的对象" class="headerlink" title="清楚构建对中产生的对象"></a>清楚构建对中产生的对象</h3><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">scons -c</span><br></pre></td></tr></table></figure>
<h3 id="让scons-简介输出"><a href="#让scons-简介输出" class="headerlink" title="让scons 简介输出"></a>让scons 简介输出</h3><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">scons -Q</span><br></pre></td></tr></table></figure>
<h3 id="设置可执行文件的名字"><a href="#设置可执行文件的名字" class="headerlink" title="设置可执行文件的名字"></a>设置可执行文件的名字</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Program(<span class="string">"HelloWorld"</span>,<span class="string">"main.cpp"</span>)</span><br><span class="line">在构建目录下产生 名字叫 HelloWorld.exe 的可执行文件</span><br><span class="line">在 POSIX 系统上产生 HelloWorld 的可执行文件</span><br><span class="line"></span><br><span class="line">如果不在 第一个参数 指定 可执行文件的名字 那么将会使用 第一个文件的名字 为可执行程序的名字</span><br></pre></td></tr></table></figure>
<h3 id="构建多个可执行程序"><a href="#构建多个可执行程序" class="headerlink" title="构建多个可执行程序"></a>构建多个可执行程序</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Program(<span class="string">'H1'</span>,[<span class="string">'main.c'</span>])</span><br><span class="line">Program(<span class="string">'H2'</span>,[<span class="string">'main1.c'</span>])</span><br><span class="line"></span><br><span class="line">只需要调用多遍 Program 这个构造器就行了</span><br></pre></td></tr></table></figure>
<h3 id="多个可执行程序-使用共同的源文件"><a href="#多个可执行程序-使用共同的源文件" class="headerlink" title="多个可执行程序 使用共同的源文件"></a>多个可执行程序 使用共同的源文件</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">common = [<span class="string">"common1.c"</span>, <span class="string">"common2.c"</span>]</span><br><span class="line">program1 = [<span class="string">"pro1.c"</span>] + common</span><br><span class="line">program2 = [<span class="string">"pro2.c"</span>] + common</span><br><span class="line"></span><br><span class="line">Program(<span class="string">"pro1"</span>,program1)</span><br><span class="line">Program(<span class="string">"pro2"</span>,program2))</span><br></pre></td></tr></table></figure>
<h3 id="构建-Library-库-从源文件中"><a href="#构建-Library-库-从源文件中" class="headerlink" title="构建 Library(库)从源文件中"></a>构建 Library(库)从源文件中</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">Library(<span class="string">'haha'</span>,[<span class="string">'main.c'</span>])</span><br><span class="line"></span><br><span class="line">你可以混合构建最终的库 scons 可以识别出来那些需要编译 </span><br><span class="line">这个只会编译 main.c</span><br><span class="line">Library(<span class="string">'haha'</span>,[<span class="string">'main.c'</span>,<span class="string">'common.o'</span>])</span><br><span class="line"></span><br><span class="line">构建静态库</span><br><span class="line">StaticLibrary()</span><br><span class="line">构建动态库</span><br><span class="line">SharedLibrary()</span><br></pre></td></tr></table></figure>
<h3 id="链接库"><a href="#链接库" class="headerlink" title="链接库"></a>链接库</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">LIBS =&gt; 指定要链接的库的名字</span><br><span class="line">LIBPATH =&gt; 要连接库名字的路径</span><br><span class="line"></span><br><span class="line">Library(<span class="string">'foo'</span>, [<span class="string">'f1.c'</span>, <span class="string">'f2.c'</span>, <span class="string">'f3.c'</span>])</span><br><span class="line">Program(<span class="string">'prog.c'</span>, LIBS=[<span class="string">'foo'</span>, <span class="string">'bar'</span>], LIBPATH=<span class="string">'.'</span>)</span><br><span class="line">这里可以简写 如果是一个 直接写库名字 不需要写成使用 列表 包一层</span><br><span class="line"></span><br><span class="line">Library(<span class="string">'foo'</span>, [<span class="string">'f1.c'</span>, <span class="string">'f2.c'</span>, <span class="string">'f3.c'</span>])</span><br><span class="line">Program(<span class="string">'prog.c'</span>, LIBS=<span class="string">'foo'</span>, LIBPATH=<span class="string">'.'</span>)</span><br><span class="line"></span><br><span class="line">多个库路径可以使用 如下格式</span><br><span class="line">[<span class="string">'/home/libs'</span>,<span class="string">'/home/gg/libs'</span>]</span><br><span class="line"><span class="string">'/home/libs:/home/gg/libs'</span>(POSIX系统上的冒号：)</span><br><span class="line"><span class="string">'C:\\libs;C:\\gg\\libs'</span>(Windows系统上的分号;)</span><br></pre></td></tr></table></figure>
<h3 id="构造其方法返回节点列表"><a href="#构造其方法返回节点列表" class="headerlink" title="构造其方法返回节点列表"></a>构造其方法返回节点列表</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">这么做的目的是让我们写的 构建文件是平台的</span><br><span class="line">不同平台 编译后的文件后缀不一样(a.obj(Windows), a.o(Lunix)) 所以 scons 帮我们处理了</span><br><span class="line">返回节点列表 soncs 去处理这些差异</span><br><span class="line">hello_list = Object(<span class="string">'hello.c'</span>, CCFLAGS=<span class="string">'-DHELLO'</span>)</span><br><span class="line">goodbye_list = Object(<span class="string">'goodbye.c'</span>, CCFLAGS=<span class="string">'-DGOODBYE'</span>)</span><br><span class="line"></span><br><span class="line">Program(hello_list + goodbye_list)</span><br><span class="line"></span><br><span class="line">打印节点列表</span><br><span class="line">print(hello_list[<span class="number">0</span>]) // hello.obj(Windows)</span><br><span class="line"></span><br><span class="line">判断文件是否存在</span><br><span class="line"><span class="keyword">if</span> <span class="keyword">not</span> os.path.exists(program_name):</span><br><span class="line">    print(<span class="string">'不存在'</span>)</span><br></pre></td></tr></table></figure>
<h3 id="清晰区分-目录节点-和-文件节点"><a href="#清晰区分-目录节点-和-文件节点" class="headerlink" title="清晰区分 目录节点 和 文件节点"></a>清晰区分 目录节点 和 文件节点</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">hello_c = File(<span class="string">'hello.c'</span>)</span><br><span class="line">Program(hello_c)</span><br><span class="line"></span><br><span class="line">目录节点</span><br><span class="line">Dir()</span><br><span class="line"></span><br><span class="line">不知道是 目录还是文件</span><br><span class="line">Entry()</span><br></pre></td></tr></table></figure>
<h3 id="从一个节点或字符串获取路径"><a href="#从一个节点或字符串获取路径" class="headerlink" title="从一个节点或字符串获取路径"></a>从一个节点或字符串获取路径</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">env=Environment(VAR=<span class="string">"value"</span>)</span><br><span class="line">n=File(<span class="string">"foo.c"</span>)</span><br><span class="line">print(env.GetBuildPath([n, <span class="string">"sub/dir/$VAR"</span>]))</span><br></pre></td></tr></table></figure>
<h3 id="重复构建-scons-可以识别出来-会出现-scons-’-is-up-to-date"><a href="#重复构建-scons-可以识别出来-会出现-scons-’-is-up-to-date" class="headerlink" title="重复构建 scons 可以识别出来 会出现 scons: `.’ is up to date."></a>重复构建 scons 可以识别出来 会出现 scons: `.’ is up to date.</h3><blockquote>
<p>指出已经是最新的了</p>
</blockquote>
<h3 id="自定义-Decider-‘MD5’"><a href="#自定义-Decider-‘MD5’" class="headerlink" title="自定义 Decider(‘MD5’)"></a>自定义 Decider(‘MD5’)</h3><blockquote>
<p>自定义 重构规则 Decider(‘MD5’) 默认是使用 md5 记录一个文件是够需要从新构建甚至 可以使用 ‘content’ 代表同名词 md5 的缺陷是 如果修改了注释 scons 也认为 没有修改<br>Decider(‘make’) 只要文件的修改时间改变就从新构建 同义词 ‘timestamp-newer’(判定规则是 比上次构建的时间戳新 就从新构建 但是有的使用会碰到 文件还原 这样就会出现 之前构建的时候 比 现在的 新 下面的 记录规则 可以解决这个问题)<br>‘timestamp-match’ 匹配时间戳是否与构建的时候一样,<br>‘MD5-timestamp’ 判定规则是  MD5 和 时间错都改变的时候 在重新构建 (如果在SCons构建文件的最后一秒内修改了源文件 这种情况可能不合适, 但是基本可能不存在)</p>
</blockquote>
<h3 id="编写自定义Decider函数"><a href="#编写自定义Decider函数" class="headerlink" title="编写自定义Decider函数"></a>编写自定义Decider函数</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line">Program(<span class="string">'hello.c'</span>)</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">decide_if_changed</span><span class="params">(dependency, target, prev_ni)</span>:</span></span><br><span class="line">    <span class="keyword">if</span> self.get_timestamp() != prev_ni.timestamp:</span><br><span class="line">        dep = str(dependency)</span><br><span class="line">        tgt = str(target)</span><br><span class="line">        <span class="keyword">if</span> specific_part_of_file_has_changed(dep, tgt):</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line">    <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line">Decider(decide_if_changed)</span><br><span class="line"></span><br><span class="line">展开第三个参数</span><br><span class="line">params :</span><br><span class="line">    prev_ni :</span><br><span class="line">        .csig The content signature, <span class="keyword">or</span> MD5 checksum, of the contents of the dependency file the list time the target was built.</span><br><span class="line">        .size The size <span class="keyword">in</span> bytes of the dependency file the list time the target was built.</span><br><span class="line">        .timestamp The modification time of the dependency file the list time the target was built.</span><br><span class="line"></span><br><span class="line">当第一次构建的时候 这个参数 prev_ni 不存在</span><br><span class="line"></span><br><span class="line">读这些东西的时候需要静心观看 不然就可能看不懂呦</span><br><span class="line"></span><br><span class="line">env = Environment()</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">config_file_decider</span><span class="params">(dependency, target, prev_ni)</span>:</span></span><br><span class="line">    <span class="keyword">import</span> os.path</span><br><span class="line"></span><br><span class="line">    <span class="comment"># We always have to init the .csig value...</span></span><br><span class="line">    <span class="comment"># 获取依赖文件的签名信息</span></span><br><span class="line">    dep_csig = dependency.get_csig()</span><br><span class="line">    <span class="comment"># .csig may not exist, because no target was built yet...</span></span><br><span class="line">    <span class="keyword">if</span> <span class="string">'csig'</span> <span class="keyword">not</span> <span class="keyword">in</span> dir(prev_ni):</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line">    <span class="comment"># Target file may not exist yet</span></span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">not</span> os.path.exists(str(target.abspath)):</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line">    <span class="keyword">if</span> dep_csig != prev_ni.csig:</span><br><span class="line">        <span class="comment"># Some change on source file =&gt; update installed one</span></span><br><span class="line">        <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line">    <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">update_file</span><span class="params">()</span>:</span></span><br><span class="line">    f = open(<span class="string">"test.txt"</span>,<span class="string">"a"</span>)</span><br><span class="line">    f.write(<span class="string">"some line\n"</span>)</span><br><span class="line">    f.close()</span><br><span class="line"></span><br><span class="line">update_file()</span><br><span class="line"></span><br><span class="line"><span class="comment"># Activate our own decider function</span></span><br><span class="line">env.Decider(config_file_decider)</span><br><span class="line"></span><br><span class="line">env.Install(<span class="string">"install"</span>,<span class="string">"test.txt"</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">不同的环境使用不同 判定规则</span><br><span class="line"></span><br><span class="line">env1 = Environment(CPPPATH = [<span class="string">'.'</span>])</span><br><span class="line">env2 = env1.Clone()</span><br><span class="line">env2.Decider(<span class="string">'timestamp-match'</span>)</span><br><span class="line">env1.Program(<span class="string">'prog-MD5'</span>, <span class="string">'program1.c'</span>)</span><br><span class="line">env2.Program(<span class="string">'prog-timestamp'</span>, <span class="string">'program2.c'</span>)</span><br></pre></td></tr></table></figure>
<h4 id="隐式构造变量"><a href="#隐式构造变量" class="headerlink" title="隐式构造变量"></a>隐式构造变量</h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* main.c */</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;hello.h&gt;</span></span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"Hello, %s!\n"</span>, <span class="built_in">string</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* hello.h */</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> string    <span class="meta-string">"world"</span></span></span><br></pre></td></tr></table></figure>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Sconsturct</span></span><br><span class="line">Program(<span class="string">'hello.c'</span>, CPPPATH = <span class="string">'.'</span>)</span><br><span class="line">也可以是多个 路径 也可以像 LIBPATH 那样</span><br><span class="line">Program(<span class="string">'hello.c'</span>, CPPPATH = [<span class="string">'include'</span>, <span class="string">'/home/project/inc'</span>])</span><br><span class="line">Window 分割符是 分号 (;) Linux 分隔符是 冒号(:)</span><br><span class="line">Program(<span class="string">'hello.c'</span>, CPPPATH = <span class="string">'include:/home/project/inc'</span>)</span><br></pre></td></tr></table></figure>
<h3 id="缓存隐式依赖关系"><a href="#缓存隐式依赖关系" class="headerlink" title="缓存隐式依赖关系"></a>缓存隐式依赖关系</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">SetOption（<span class="string">'implicit_cache'</span>，<span class="number">1</span>）</span><br></pre></td></tr></table></figure>
<p>或则是使用命令行 </p>
<blockquote>
<p>scons -Q –implicit-cache</p>
</blockquote>
<blockquote>
<p>scons -Q –implicit-deps-changed 通知 scons 跟新隐式缓存 依赖的文件改变时</p>
</blockquote>
<blockquote>
<p>scons -Q –implicit-deps-unchanged 强制及时依赖的文件改变时 仍然使用 缓存依赖</p>
</blockquote>
<h3 id="显示依赖关系"><a href="#显示依赖关系" class="headerlink" title="显示依赖关系"></a>显示依赖关系</h3><p>有的时候 scons 没有扫描(detected)到依赖关系的时候 scons 允许你 显示指定 依赖关系</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">hello = Program(<span class="string">'hello.c'</span>)</span><br><span class="line">Depends(hello, <span class="string">'other_file'</span>)</span><br><span class="line"></span><br><span class="line">Depends 的第二个参数 也可以是节点 列表</span><br><span class="line"></span><br><span class="line">hello = Program(<span class="string">'hello.c'</span>)</span><br><span class="line">goodbye = Program(<span class="string">'goodbye.c'</span>)</span><br><span class="line">Depends(hello, goodbye)</span><br></pre></td></tr></table></figure>
<h3 id="外部文件的依赖关系：ParseDepends-功能"><a href="#外部文件的依赖关系：ParseDepends-功能" class="headerlink" title="外部文件的依赖关系：ParseDepends 功能"></a>外部文件的依赖关系：ParseDepends 功能</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">define</span> FOO_HEADER <span class="meta-string">&lt;foo.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> FOO_HEADER</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> FOO;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>上面这种情况 scons 可能无法 知道依赖关系</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">obj = Object(<span class="string">'hello.c'</span>, CCFLAGS=<span class="string">'-MD -MF hello.d'</span>, CPPPATH=<span class="string">'.'</span>)</span><br><span class="line">SideEffect(<span class="string">'hello.d'</span>, obj)</span><br><span class="line">ParseDepends(<span class="string">'hello.d'</span>)</span><br><span class="line"> Program(<span class="string">'hello'</span>, obj)</span><br></pre></td></tr></table></figure>
<p>借助编译器 对宏的展开 并生成一个 <em>.d 的文件 第一次 scons 无法检测依赖 第二次 scons 可以根据生成的 </em>.d的文件确定依赖关系</p>
<h3 id="忽略依赖项"><a href="#忽略依赖项" class="headerlink" title="忽略依赖项"></a>忽略依赖项</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">hello_obj=Object(<span class="string">'hello.c'</span>)</span><br><span class="line">hello = Program(hello_obj)</span><br><span class="line">Ignore(hello_obj, <span class="string">'hello.h'</span>)</span><br><span class="line"></span><br><span class="line">上面的例子可能很难想象 它依赖的头文件 改变了 不从新编译</span><br><span class="line">有一种情况 比如多个系统 使用同一个 头文件 每个系统的头文件 会有略微的差异</span><br><span class="line">此时依赖的头文件改变了 但是不需要重新编译</span><br><span class="line">hello = Program(<span class="string">'hello.c'</span>, CPPPATH=[<span class="string">'/usr/include'</span>])</span><br><span class="line">Ignore(hello, <span class="string">'/usr/include/stdio.h'</span>)</span><br><span class="line"></span><br><span class="line">hello_obj=Object(<span class="string">'hello.c'</span>)</span><br><span class="line">hello = Program(hello_obj)</span><br><span class="line">Ignore(<span class="string">'.'</span>,[hello,hello_obj])</span><br></pre></td></tr></table></figure>
<h3 id="AlwaysBuild"><a href="#AlwaysBuild" class="headerlink" title="AlwaysBuild"></a>AlwaysBuild</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">hello = Program(<span class="string">'hello.c'</span>)</span><br><span class="line">AlwaysBuild(hello)</span><br></pre></td></tr></table></figure>
<h3 id="构造环境feature的使用"><a href="#构造环境feature的使用" class="headerlink" title="构造环境feature的使用"></a>构造环境feature的使用</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br></pre></td><td class="code"><pre><span class="line">创建新的 构造环境</span><br><span class="line">env = Environment()</span><br><span class="line"></span><br><span class="line">一个简单的例子 设置 c编译器</span><br><span class="line"> env = Environment(CC = <span class="string">'gcc'</span>, CCFLAGS = <span class="string">'-O2'</span>)</span><br><span class="line"> env.Program(<span class="string">'foo.c'</span>)</span><br><span class="line"></span><br><span class="line">访问构造环境的各个变量  (它是个具有关联方法的对象)</span><br><span class="line">env = Environment()</span><br><span class="line">print(<span class="string">"CC is: %s"</span>%env[<span class="string">'CC'</span>])</span><br><span class="line"></span><br><span class="line">如果你仅仅是访问他的构造变量,你可以这样做 调用构造环境的 Dictionary 方法</span><br><span class="line">env = Environment(FOO = <span class="string">'foo'</span>, BAR = <span class="string">'bar'</span>)</span><br><span class="line">dict = env.Dictionary()</span><br><span class="line"><span class="keyword">for</span> key <span class="keyword">in</span> [<span class="string">'OBJSUFFIX'</span>, <span class="string">'LIBSUFFIX'</span>, <span class="string">'PROGSUFFIX'</span>]:</span><br><span class="line">    print(<span class="string">"key = %s, value = %s"</span> % (key, dict[key]))</span><br><span class="line"></span><br><span class="line">on Windows &gt; OBJSUFFIX =&gt; .obj LIBSUFFIX =&gt; .lib PROGSUFFIX =&gt; .exe</span><br><span class="line">on Linux &gt; OBJSUFFIX =&gt; .o LIBSUFFIX =&gt; .a PROGSUFFIX =&gt; </span><br><span class="line"></span><br><span class="line">获取构造环境中的变量 方法<span class="number">2</span></span><br><span class="line">使用 subst() 方法 使用 $ + 变量字段 的方式访问</span><br><span class="line">使用这个方法的好处是 它可以将构造变量展开</span><br><span class="line">env = Environment()</span><br><span class="line">print(<span class="string">"CC is: %s"</span>%env.subst(<span class="string">'$CC'</span>))</span><br><span class="line"><span class="comment"># $CCCOM</span></span><br><span class="line"></span><br><span class="line">处理 变量 展开带来的问题</span><br><span class="line">如果访问一个不存在的变量是 scons 并不会报错 </span><br><span class="line">如果想要报错你可以这样做</span><br><span class="line">AllowSubstExceptions() 开始 使用 subst 函数异常的功能 这是个全局变量</span><br><span class="line"></span><br><span class="line">除了定义默认的异常外 还可以定义 其他异常如 零除异常</span><br><span class="line">AllowSubstExceptions(IndexError, NameError, ZeroDivisionError)</span><br><span class="line">env = Environment()</span><br><span class="line">print(<span class="string">"value is: %s"</span>%env.subst( <span class="string">'-&gt;$&#123;1 / 0&#125;&lt;-'</span> ))</span><br><span class="line"></span><br><span class="line">创建默认的 构造环境 可以设置 目标编译器</span><br><span class="line">DefaultEnvironment(CC = <span class="string">'/usr/local/bin/gcc'</span>)</span><br><span class="line"></span><br><span class="line">当然也可以这样做</span><br><span class="line">env = DefaultEnvironment()</span><br><span class="line">env[<span class="string">'CC'</span>] = <span class="string">'/usr/local/bin/gcc'</span></span><br><span class="line"></span><br><span class="line">使用 DefaultEnvironment() 可以加快你初始化构造变量</span><br><span class="line">在初始化时 scons 会在 系统的环境变量中搜索 可用的 编译器 连接器等 你可以指定 搜索的 工具 加快scons的初始化速度 你可以这样做</span><br><span class="line"></span><br><span class="line">直接指定 编译工具 链接工具 指定 c编译器 为gcc</span><br><span class="line">env = DefaultEnvironment(tools = [<span class="string">'gcc'</span>, <span class="string">'gnulink'</span>],</span><br><span class="line">                         CC = <span class="string">'/usr/local/bin/gcc'</span>)</span><br><span class="line"></span><br><span class="line">多构造环境 你可以这样做 不同的构造环境 使用不同的配置</span><br><span class="line">opt = Environment(CCFLAGS = <span class="string">'-O2'</span>)</span><br><span class="line">dbg = Environment(CCFLAGS = <span class="string">'-g'</span>)</span><br><span class="line"></span><br><span class="line">opt.Program(<span class="string">'foo'</span>, <span class="string">'foo.c'</span>)</span><br><span class="line">dbg.Program(<span class="string">'foo'</span>, <span class="string">'foo.c'</span>)</span><br><span class="line">--------------------------------------</span><br><span class="line">产生编译产物 *.obj(on Windows)</span><br><span class="line">opt = Environment(CCFLAGS = <span class="string">'-O2'</span>)</span><br><span class="line">dbg = Environment(CCFLAGS = <span class="string">'-g'</span>)</span><br><span class="line"></span><br><span class="line">o = opt.Object(<span class="string">'foo-opt'</span>, <span class="string">'foo.c'</span>)</span><br><span class="line">opt.Program(o)</span><br><span class="line"></span><br><span class="line">d = dbg.Object(<span class="string">'foo-dbg'</span>, <span class="string">'foo.c'</span>)</span><br><span class="line">dbg.Program(d)</span><br><span class="line"></span><br><span class="line">克隆当前的环境变量</span><br><span class="line">克隆一份一模一样的构造环境</span><br><span class="line">env = Environment(CC = <span class="string">'gcc'</span>)</span><br><span class="line">opt = env.Clone(CCFLAGS = <span class="string">'-O2'</span>)</span><br><span class="line">dbg = env.Clone(CCFLAGS = <span class="string">'-g'</span>)</span><br><span class="line">env.Program(<span class="string">'foo'</span>, <span class="string">'foo.c'</span>)</span><br><span class="line">o = opt.Object(<span class="string">'foo-opt'</span>, <span class="string">'foo.c'</span>)</span><br><span class="line">opt.Program(o)</span><br><span class="line">d = dbg.Object(<span class="string">'foo-dbg'</span>, <span class="string">'foo.c'</span>)</span><br><span class="line">dbg.Program(d)</span><br><span class="line"></span><br><span class="line">替换构造环境</span><br><span class="line">env = Environment(CCFLAGS = <span class="string">'-DDEFINE1'</span>)</span><br><span class="line">env.Replace(CCFLAGS = <span class="string">'-DDEFINE2'</span>)</span><br><span class="line">env.Program(<span class="string">'foo.c'</span>)</span><br><span class="line"></span><br><span class="line">仅在尚未定义的情况下设置值</span><br><span class="line">env.SetDefault(SPECIAL_FLAG = <span class="string">'-extra-option'</span>)</span><br><span class="line"></span><br><span class="line">附加到构造变量末尾</span><br><span class="line">env = Environment(CCFLAGS = [<span class="string">'-DMY_VALUE'</span>])</span><br><span class="line">env.Append(CCFLAGS = [<span class="string">'-DLAST'</span>])</span><br><span class="line">env.Program(<span class="string">'foo.c'</span>)</span><br><span class="line"></span><br><span class="line">附加唯一值</span><br><span class="line">Some times it<span class="string">'s useful to add a new value only if the existing construction variable doesn'</span>t already contain the value. This can be done using the AppendUnique method:</span><br><span class="line">官方解释: 有时 它是有用的 在这个构造变量没有包含这个变量的时候添加一个新值 , 这样可以使使用这个 方法做</span><br><span class="line">env.AppendUnique(CCFLAGS=[<span class="string">'-g'</span>])</span><br><span class="line"></span><br><span class="line">In the above example, the -g would be added only <span class="keyword">if</span> the $CCFLAGS variable does <span class="keyword">not</span> already contain a -g value.</span><br><span class="line">解释: 在上面这个例子, -g 标识将被添加 仅仅这个 $CCFLAGS 变量曾没有包含这个 -g 的标识</span><br><span class="line"></span><br><span class="line">附加到值的开头</span><br><span class="line">env = Environment(CCFLAGS = [<span class="string">'-DMY_VALUE'</span>])</span><br><span class="line">env.Prepend(CCFLAGS = [<span class="string">'-DFIRST'</span>])</span><br><span class="line">env.Program(<span class="string">'foo.c'</span>)</span><br><span class="line"></span><br><span class="line">附加唯一值到开头 和上面在结尾附加值 的 逻辑是一样的</span><br><span class="line">env.PrependUnique（CCFLAGS = [ <span class="string">' -  G'</span>]）</span><br></pre></td></tr></table></figure>
            <div class="post-copyright">
    <div class="content">
        <p>最后更新： 2019年08月14日 11:22</p>
        <p>原始链接： <a class="post-url" href="/posts/79065537/" title="scons自动构建工具">https://leng521.top/posts/79065537/</a></p>
        <footer>
            <a href="https://leng521.top">
                <img src="/head.jpg" alt="小魏">
                小魏
            </a>
        </footer>
    </div>
</div>

      
        
            

        
    </div>
    <footer class="article-footer">
        
        
<div class="post-share">
    <a href="javascript:;" id="share-sub" class="post-share-fab">
        <i class="fa fa-share-alt"></i>
    </a>
    <div class="post-share-list" id="share-list">
        <ul class="share-icons">
          <li>
            <a class="weibo share-sns" target="_blank" href="http://service.weibo.com/share/share.php?url=https://leng521.top/posts/79065537/&title=《scons自动构建工具》 — 小魏的博客&pic=https://leng521.tophead.jpg" data-title="微博">
              <i class="fa fa-weibo"></i>
            </a>
          </li>
          <li>
            <a class="weixin share-sns" id="wxFab" href="javascript:;" data-title="微信">
              <i class="fa fa-weixin"></i>
            </a>
          </li>
          <li>
            <a class="qq share-sns" target="_blank" href="http://connect.qq.com/widget/shareqq/index.html?url=https://leng521.top/posts/79065537/&title=《scons自动构建工具》 — 小魏的博客&source=这篇文章可能有点长,如果你想要学到一些知识,而不是简单入门,你要有耐心的看下去,当然在看的时候,也要自己思考,也许我写的有问题,这个时候你可以再去看看,官..." data-title="QQ">
              <i class="fa fa-qq"></i>
            </a>
          </li>
          <li>
            <a class="facebook share-sns" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=https://leng521.top/posts/79065537/" data-title="Facebook">
              <i class="fa fa-facebook"></i>
            </a>
          </li>
          <li>
            <a class="twitter share-sns" target="_blank" href="https://twitter.com/intent/tweet?text=《scons自动构建工具》 — 小魏的博客&url=https://leng521.top/posts/79065537/&via=https://leng521.top" data-title="Twitter">
              <i class="fa fa-twitter"></i>
            </a>
          </li>
          <li>
            <a class="google share-sns" target="_blank" href="https://plus.google.com/share?url=https://leng521.top/posts/79065537/" data-title="Google+">
              <i class="fa fa-google-plus"></i>
            </a>
          </li>
        </ul>
     </div>
</div>
<div class="post-modal wx-share" id="wxShare">
    <a class="close" href="javascript:;" id="wxShare-close">×</a>
    <p>扫一扫，分享到微信</p>
    <img src="" alt="微信分享二维码">
</div>

<div class="mask"></div>

        
        <ul class="article-footer-menu">
            
            
  <li class="article-footer-tags">
    <i class="fa fa-tags"></i>
      
    <a href="/tags/python/" class="color2">python</a>
      
    <a href="/tags/c++/" class="color4">c++</a>
      
    <a href="/tags/scons/" class="color1">scons</a>
      
  </li>

        </ul>
        
    </footer>
  </div>
</article>


    <aside class="post-toc-pos post-toc-top" id="post-toc">
        <nav class="post-toc-wrap">
            <ol class="post-toc"><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#scons-普通简单的构建"><span class="post-toc-text">scons 普通简单的构建</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#多个文件构建"><span class="post-toc-text">多个文件构建</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#Object-构建方法"><span class="post-toc-text">Object 构建方法</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#清楚构建对中产生的对象"><span class="post-toc-text">清楚构建对中产生的对象</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#让scons-简介输出"><span class="post-toc-text">让scons 简介输出</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#设置可执行文件的名字"><span class="post-toc-text">设置可执行文件的名字</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#构建多个可执行程序"><span class="post-toc-text">构建多个可执行程序</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#多个可执行程序-使用共同的源文件"><span class="post-toc-text">多个可执行程序 使用共同的源文件</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#构建-Library-库-从源文件中"><span class="post-toc-text">构建 Library(库)从源文件中</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#链接库"><span class="post-toc-text">链接库</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#构造其方法返回节点列表"><span class="post-toc-text">构造其方法返回节点列表</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#清晰区分-目录节点-和-文件节点"><span class="post-toc-text">清晰区分 目录节点 和 文件节点</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#从一个节点或字符串获取路径"><span class="post-toc-text">从一个节点或字符串获取路径</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#重复构建-scons-可以识别出来-会出现-scons-’-is-up-to-date"><span class="post-toc-text">重复构建 scons 可以识别出来 会出现 scons: `.’ is up to date.</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#自定义-Decider-‘MD5’"><span class="post-toc-text">自定义 Decider(‘MD5’)</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#编写自定义Decider函数"><span class="post-toc-text">编写自定义Decider函数</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#隐式构造变量"><span class="post-toc-text">隐式构造变量</span></a></li></ol></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#缓存隐式依赖关系"><span class="post-toc-text">缓存隐式依赖关系</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#显示依赖关系"><span class="post-toc-text">显示依赖关系</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#外部文件的依赖关系：ParseDepends-功能"><span class="post-toc-text">外部文件的依赖关系：ParseDepends 功能</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#忽略依赖项"><span class="post-toc-text">忽略依赖项</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#AlwaysBuild"><span class="post-toc-text">AlwaysBuild</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#构造环境feature的使用"><span class="post-toc-text">构造环境feature的使用</span></a></li></ol>
        </nav>
    </aside>
    

<nav id="article-nav">
  
    <a href="/posts/66615451/" id="article-nav-newer" class="article-nav-link-wrap">

      <span class="article-nav-title">
        <i class="fa fa-hand-o-left" aria-hidden="true"></i>
        
          scons自动构建工具(二)
        
      </span>
    </a>
  
  
    <a href="/posts/41d43874/" id="article-nav-older" class="article-nav-link-wrap">
      <span class="article-nav-title">cocos2dx-JS-OC-Java互相调用</span>
      <i class="fa fa-hand-o-right" aria-hidden="true"></i>
    </a>
  
</nav>



    
        <!-- 来必力City版安装代码 -->
<div id="lv-container" data-id="city" data-uid="MTAyMC8zNDA0MC8xMDU3OA==">
<script type="text/javascript">
   (function(d, s) {
       var j, e = d.getElementsByTagName(s)[0];

       if (typeof LivereTower === 'function') { return; }

       j = d.createElement(s);
       j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
       j.async = true;

       e.parentNode.insertBefore(j, e);
   })(document, 'script');
</script>
<noscript>为正常使用来必力评论功能请激活JavaScript</noscript>
</div>
<!-- City版安装代码已完成 -->
    
</section>
        
      </div>
      <footer id="footer">
  <div class="outer">
    <div id="footer-info" class="inner">
      
<p>
    <span id="busuanzi_container_site_uv" style='display:none'>
        总访客数：<span id="busuanzi_value_site_uv"></span>
    </span>
    <span id="busuanzi_container_site_pv" style='display:none'>
        总访问量：<span id="busuanzi_value_site_pv"></span>
    </span>
</p>


      <p>
        Powered by  <a href="http://hexo.io/" target="_blank">Hexo</a>
        Theme <a href="//github.com/wongminho/hexo-theme-miho" target="_blank">MiHo</a>
      &copy; 2019 小魏<br>
      </p>
    </div>
  </div>
</footer>
    <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<script src="//cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script>
  var mihoConfig = {
      root: "https://leng521.top",
      animate: true,
      isHome: false,
      share: true,
      reward: 0
  }
</script>
<div class="sidebar">
    <div id="sidebar-search" title="Search">
        <i class="fa fa-search"></i>
    </div>
    <div id="sidebar-category" title="Categories">
        <i class="fa fa-book"></i>
    </div>
    <div id="sidebar-tag" title="Tags">
        <i class="fa fa-tags"></i>
    </div>
    <div id="sidebar-top">
        <span class="sidebar-top-icon"><i class="fa fa-angle-up"></i></span>
    </div>
</div>
<div class="sidebar-menu-box" id="sidebar-menu-box">
    <div class="sidebar-menu-box-container">
        <div id="sidebar-menu-box-categories">
            <a class="category-link" href="/categories/Cocos-Creator/">Cocos Creator</a><a class="category-link" href="/categories/QQ玩一玩/">QQ玩一玩</a><a class="category-link" href="/categories/cocos2d-x/">cocos2d-x</a><a class="category-link" href="/categories/cocos2dx/">cocos2dx</a><a class="category-link" href="/categories/git/">git</a><a class="category-link" href="/categories/hexo/">hexo</a><a class="category-link" href="/categories/js/">js</a><a class="category-link" href="/categories/linux/">linux</a><a class="category-link" href="/categories/python/">python</a><a class="category-link" href="/categories/前端/">前端</a><a class="category-link" href="/categories/前端/WebGL/">WebGL</a><a class="category-link" href="/categories/前端/bgfx/">bgfx</a><a class="category-link" href="/categories/后端/">后端</a><a class="category-link" href="/categories/后端/golang/">golang</a><a class="category-link" href="/categories/后端/golang/protobuf/">protobuf</a><a class="category-link" href="/categories/后端/nodejs/">nodejs</a><a class="category-link" href="/categories/微信小游戏/">微信小游戏</a><a class="category-link" href="/categories/插件/">插件</a><a class="category-link" href="/categories/自动构建工具/">自动构建工具</a>
        </div>
        <div id="sidebar-menu-box-tags">
            <a href="/tags/9宫格/" style="font-size: 10px;">9宫格</a> <a href="/tags/Cocos-Creator/" style="font-size: 20px;">Cocos Creator</a> <a href="/tags/IT/" style="font-size: 10px;">IT</a> <a href="/tags/QQ玩一玩/" style="font-size: 10px;">QQ玩一玩</a> <a href="/tags/TweenLite/" style="font-size: 10px;">TweenLite</a> <a href="/tags/WebGL/" style="font-size: 10px;">WebGL</a> <a href="/tags/android-studio/" style="font-size: 10px;">android studio</a> <a href="/tags/bgfx/" style="font-size: 12.5px;">bgfx</a> <a href="/tags/c/" style="font-size: 12.5px;">c++</a> <a href="/tags/cocos2d-x/" style="font-size: 15px;">cocos2d-x</a> <a href="/tags/cpp/" style="font-size: 12.5px;">cpp</a> <a href="/tags/gcc/" style="font-size: 10px;">gcc</a> <a href="/tags/git/" style="font-size: 10px;">git</a> <a href="/tags/git-扩展工具/" style="font-size: 10px;">git 扩展工具</a> <a href="/tags/github-page/" style="font-size: 10px;">github page</a> <a href="/tags/git命令/" style="font-size: 10px;">git命令</a> <a href="/tags/golang/" style="font-size: 15px;">golang</a> <a href="/tags/hello-world/" style="font-size: 10px;">hello world</a> <a href="/tags/hexo/" style="font-size: 12.5px;">hexo</a> <a href="/tags/js/" style="font-size: 12.5px;">js</a> <a href="/tags/lua/" style="font-size: 12.5px;">lua</a> <a href="/tags/nodejs/" style="font-size: 10px;">nodejs</a> <a href="/tags/optionParser/" style="font-size: 10px;">optionParser</a> <a href="/tags/protobuf/" style="font-size: 10px;">protobuf</a> <a href="/tags/python/" style="font-size: 17.5px;">python</a> <a href="/tags/scons/" style="font-size: 12.5px;">scons</a> <a href="/tags/spine/" style="font-size: 10px;">spine</a> <a href="/tags/sublime插件/" style="font-size: 10px;">sublime插件</a> <a href="/tags/websocket/" style="font-size: 10px;">websocket</a> <a href="/tags/xmake/" style="font-size: 12.5px;">xmake</a> <a href="/tags/优化/" style="font-size: 12.5px;">优化</a> <a href="/tags/前端/" style="font-size: 15px;">前端</a> <a href="/tags/博客/" style="font-size: 10px;">博客</a> <a href="/tags/原型链/" style="font-size: 10px;">原型链</a> <a href="/tags/后端/" style="font-size: 10px;">后端</a> <a href="/tags/广告/" style="font-size: 10px;">广告</a> <a href="/tags/微信小游戏/" style="font-size: 20px;">微信小游戏</a> <a href="/tags/缺少dll/" style="font-size: 10px;">缺少dll</a> <a href="/tags/闭包/" style="font-size: 10px;">闭包</a>
        </div>
    </div>
    <a href="javascript:;" class="sidebar-menu-box-close">&times;</a>
</div>
<div class="mobile-header-menu-nav" id="mobile-header-menu-nav">
    <div class="mobile-header-menu-container">
        <span class="title">Menus</span>
        <ul class="mobile-header-menu-navbar">
            
            <li>
                <a  href="/">
                    <i class="fa fa-home"></i><span>Home</span>
                </a>
            </li>
            
            <li>
                <a  href="/archives">
                    <i class="fa fa-archive"></i><span>Archives</span>
                </a>
            </li>
            
            <li>
                <a  href="/about">
                    <i class="fa fa-user"></i><span>About</span>
                </a>
            </li>
            
        </ul>
    </div>
    <div class="mobile-header-tag-container">
        <span class="title">Tags</span>
        <div id="mobile-header-container-tags">
            <a href="/tags/9宫格/" style="font-size: 10px;">9宫格</a> <a href="/tags/Cocos-Creator/" style="font-size: 20px;">Cocos Creator</a> <a href="/tags/IT/" style="font-size: 10px;">IT</a> <a href="/tags/QQ玩一玩/" style="font-size: 10px;">QQ玩一玩</a> <a href="/tags/TweenLite/" style="font-size: 10px;">TweenLite</a> <a href="/tags/WebGL/" style="font-size: 10px;">WebGL</a> <a href="/tags/android-studio/" style="font-size: 10px;">android studio</a> <a href="/tags/bgfx/" style="font-size: 12.5px;">bgfx</a> <a href="/tags/c/" style="font-size: 12.5px;">c++</a> <a href="/tags/cocos2d-x/" style="font-size: 15px;">cocos2d-x</a> <a href="/tags/cpp/" style="font-size: 12.5px;">cpp</a> <a href="/tags/gcc/" style="font-size: 10px;">gcc</a> <a href="/tags/git/" style="font-size: 10px;">git</a> <a href="/tags/git-扩展工具/" style="font-size: 10px;">git 扩展工具</a> <a href="/tags/github-page/" style="font-size: 10px;">github page</a> <a href="/tags/git命令/" style="font-size: 10px;">git命令</a> <a href="/tags/golang/" style="font-size: 15px;">golang</a> <a href="/tags/hello-world/" style="font-size: 10px;">hello world</a> <a href="/tags/hexo/" style="font-size: 12.5px;">hexo</a> <a href="/tags/js/" style="font-size: 12.5px;">js</a> <a href="/tags/lua/" style="font-size: 12.5px;">lua</a> <a href="/tags/nodejs/" style="font-size: 10px;">nodejs</a> <a href="/tags/optionParser/" style="font-size: 10px;">optionParser</a> <a href="/tags/protobuf/" style="font-size: 10px;">protobuf</a> <a href="/tags/python/" style="font-size: 17.5px;">python</a> <a href="/tags/scons/" style="font-size: 12.5px;">scons</a> <a href="/tags/spine/" style="font-size: 10px;">spine</a> <a href="/tags/sublime插件/" style="font-size: 10px;">sublime插件</a> <a href="/tags/websocket/" style="font-size: 10px;">websocket</a> <a href="/tags/xmake/" style="font-size: 12.5px;">xmake</a> <a href="/tags/优化/" style="font-size: 12.5px;">优化</a> <a href="/tags/前端/" style="font-size: 15px;">前端</a> <a href="/tags/博客/" style="font-size: 10px;">博客</a> <a href="/tags/原型链/" style="font-size: 10px;">原型链</a> <a href="/tags/后端/" style="font-size: 10px;">后端</a> <a href="/tags/广告/" style="font-size: 10px;">广告</a> <a href="/tags/微信小游戏/" style="font-size: 20px;">微信小游戏</a> <a href="/tags/缺少dll/" style="font-size: 10px;">缺少dll</a> <a href="/tags/闭包/" style="font-size: 10px;">闭包</a>
        </div>
    </div>
</div>
<div class="search-wrap">
    <span class="search-close">&times;</span>
        <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="back">
            <i class="icon icon-lg icon-chevron-left"></i>
        </a>
        <input class="search-field" placeholder="Search..." id="keywords">
        <a id="search-submit" href="javascript:;">
            <i class="fa fa-search"></i>
        </a>
    <div class="search-container" id="search-container">
        <ul class="search-result" id="search-result">
        </ul>
    </div>
</div>

<div id="search-tpl">
    <li class="search-result-item">
        <a href="{url}" class="search-item-li">
            <span class="search-item-li-title" title="{title}">{title}</span>
        </a>
    </li>
</div>
<script src="/js/search.js"></script>
<script src="/js/main.js"></script>


  <script src="//cdn.bootcss.com/particles.js/2.0.0/particles.min.js"></script>
  <div id="particles"></div>
  <script src="/js/particles.js"></script>







  <link rel="stylesheet" href="//cdn.bootcss.com/animate.css/3.5.0/animate.min.css">
  <script src="//cdn.bootcss.com/scrollReveal.js/3.0.5/scrollreveal.js"></script>
  <script src="/js/animate.js"></script>


  <script src="/js/pop-img.js"></script>
  <script>
     $(".article-entry p img").popImg();
  </script>

  </div>
</body>
</html>